package com.easylinkin.linkappapi.grid.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.core.utils.CollectionUtils;
import com.easylinkin.linkappapi.grid.entity.GridInfo;
import com.easylinkin.linkappapi.grid.entity.GridQrCode;
import com.easylinkin.linkappapi.grid.entity.GridUser;
import com.easylinkin.linkappapi.grid.mapper.GridInfoMapper;
import com.easylinkin.linkappapi.grid.mapper.GridQrCodeMapper;
import com.easylinkin.linkappapi.grid.mapper.GridUserMapper;
import com.easylinkin.linkappapi.grid.models.dto.GridInfoDTO;
import com.easylinkin.linkappapi.grid.models.dto.GridQrDTO;
import com.easylinkin.linkappapi.grid.models.dto.GridRoleDTO;
import com.easylinkin.linkappapi.grid.models.dto.GridUserDTO;
import com.easylinkin.linkappapi.grid.models.vo.GridInfoVO;
import com.easylinkin.linkappapi.grid.models.vo.GridListVO;
import com.easylinkin.linkappapi.grid.models.vo.GridUserSelectVO;
import com.easylinkin.linkappapi.grid.service.IGridInfoService;
import com.easylinkin.linkappapi.grid.service.IGridQrCodeService;
import com.easylinkin.linkappapi.grid.service.IGridUserService;
import com.easylinkin.linkappapi.lobar.entity.UserProject;
import com.easylinkin.linkappapi.lobar.service.UserProjectService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 网格信息表 服务实现类
 *
 * @author
 * @since 2024-05-15
 */
@Service
public class GridInfoServiceImpl extends ServiceImpl<GridInfoMapper, GridInfo> implements IGridInfoService {

    @Autowired
    private GridInfoMapper gridInfoMapper;
    @Autowired
    private LinkappUserContextProducer linkappUserContextProducer;
    @Autowired
    private IGridUserService iGridUserService;
    @Autowired
    private UserProjectService userProjectService;
    @Autowired
    private GridUserMapper gridUserMapper;
    @Autowired
    private IGridQrCodeService gridQrCodeService;

    /**
     * 新增网格信息
     *
     * @param gridInfoDTO:
     * @return site.morn.rest.RestMessage
     * @author Jereay
     * @date 2024/5/15 16:23
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestMessage addGridInfo(GridInfoDTO gridInfoDTO) {
        // 获取当前登录用户
        LinkappUser user = linkappUserContextProducer.getNotNullCurrent();

        GridInfo gridInfo = new GridInfo();
        gridInfo.setGridName(gridInfoDTO.getGridName());
        gridInfo.setGridLevel(gridInfoDTO.getGridLevel());
        gridInfo.setParentId(gridInfoDTO.getParentId());
        gridInfo.setCreateTime(LocalDateTime.now());
        gridInfo.setCreatorId(user.getId().toString());
        gridInfo.setTenantId(user.getTenantId());
        int insert = this.gridInfoMapper.insert(gridInfo);
        if (insert > 0) {
            List<GridUser> roleList = new ArrayList<>();
            // 保存网格角色
            for (GridRoleDTO role : gridInfoDTO.getRoleList()) {
                GridUser gridUser = new GridUser();
                gridUser.setGridRoleName(role.getGridRoleName());
                gridUser.setTenantId(user.getTenantId());
                gridUser.setGridId(gridInfo.getId());
                roleList.add(gridUser);
            }
            boolean b = this.iGridUserService.saveBatch(roleList);
            if (b) {
                return RestBuilders.successBuilder().message("新增成功").build();
            }
            throw new RuntimeException("保存网格角色失败");
        }

        return RestBuilders.errorBuilder().message("新增失败").build();
    }

    /**
     * 修改网格信息
     *
     * @param gridInfoDTO:
     * @return site.morn.rest.RestMessage
     * @author Jereay
     * @date 2024/5/15 16:23
     */
    @Override
    public RestMessage updateGridInfo(GridInfoDTO gridInfoDTO) {
        // 获取当前登录用户
        LinkappUser user = linkappUserContextProducer.getNotNullCurrent();

        GridInfo gridInfo = new GridInfo();
        gridInfo.setId(gridInfoDTO.getId());
        gridInfo.setGridName(gridInfoDTO.getGridName());
        gridInfo.setGridLevel(gridInfoDTO.getGridLevel());
        gridInfo.setParentId(gridInfoDTO.getParentId());
        gridInfo.setModifyTime(LocalDateTime.now());
        gridInfo.setModifyId(user.getId().toString());
        int update = this.gridInfoMapper.updateById(gridInfo);
        if (update > 0) {
            // 查询原有角色
            List<GridUser> gridUsers = this.iGridUserService.list(Wrappers.<GridUser>lambdaQuery().eq(GridUser::getGridId, gridInfo.getId()));
            List<Integer> oldId = new ArrayList<>();
            List<Integer> newId = new ArrayList<>();
            if(ObjectUtil.isNotEmpty(gridUsers)){
                oldId = gridUsers.stream().map(GridUser::getId).collect(Collectors.toList());
            }
            List<GridUser> roleList = new ArrayList<>();
            // 保存网格角色
            for (GridRoleDTO role : gridInfoDTO.getRoleList()) {
                GridUser gridUser = new GridUser();
                gridUser.setGridRoleName(role.getGridRoleName());
                gridUser.setTenantId(user.getTenantId());
                gridUser.setGridId(gridInfo.getId());
                if(ObjectUtil.isNotNull(role.getId())){
                    newId.add(role.getId());
                    gridUser.setId(role.getId());
                }
                roleList.add(gridUser);
            }
            // 删除页面删除的角色
            if(CollectionUtil.isNotEmpty(oldId)){
                oldId.removeAll(newId);
                if(CollectionUtil.isNotEmpty(oldId)){
                    iGridUserService.remove(Wrappers.<GridUser>lambdaUpdate()
                            .eq(GridUser::getGridId, gridInfo.getId())
                            .in(GridUser::getId, oldId)
                    );
                }

            }

            boolean b = this.iGridUserService.saveOrUpdateBatch(roleList);
            if (b) {
                return RestBuilders.successBuilder().message("修改成功").build();
            }
            throw new RuntimeException("修改网格角色失败");
        }

        return RestBuilders.errorBuilder().message("修改失败").build();
    }

    /**
     * 获取所有网格信息
     *
     * @return site.morn.rest.RestMessage
     * @author Jereay
     * @date 2024/5/15 16:24
     */
    @Override
    public RestMessage queryInfo() {
        // 获取当前登录用户
        LinkappUser user = linkappUserContextProducer.getNotNullCurrent();
        // 查询所有网格
        List<GridInfo> gridInfos = this.gridInfoMapper.selectList(Wrappers.<GridInfo>lambdaQuery()
                .eq(GridInfo::getTenantId, user.getTenantId())
                .lt(GridInfo::getGridLevel, 3)
        );
        // 三级网格
        List<GridInfo> thirdGridInfos = this.gridInfoMapper.selectList(Wrappers.<GridInfo>lambdaQuery()
                .eq(GridInfo::getTenantId, user.getTenantId())
                .eq(GridInfo::getGridLevel, 3)
        );
        Map<Integer, GridInfo> thirdGridMap = null;
        if (CollectionUtil.isNotEmpty(thirdGridInfos)) {
            thirdGridMap = thirdGridInfos.stream()
                    .collect(Collectors.toMap(GridInfo::getParentId, Function.identity()));
        }
        // 网格数据组合
        if (CollectionUtil.isNotEmpty(gridInfos)) {
            List<GridInfoVO> firstGridList = new ArrayList<>();
            List<GridInfoVO> secondGridList = new ArrayList<>();
            for (GridInfo gridInfo : gridInfos) {
                if (1 == gridInfo.getGridLevel()) {
                    GridInfoVO gridInfoVO = BeanUtil.copyProperties(gridInfo, GridInfoVO.class);
                    // 查询用户信息
                    List<GridUser> gridUsers = iGridUserService.list(Wrappers.<GridUser>lambdaQuery().eq(GridUser::getGridId, gridInfoVO.getId()));
                    if (CollectionUtil.isNotEmpty(gridUsers)) {
                        List<GridRoleDTO> gridRoleDTOS = new ArrayList<>();
                        for (GridUser gridUser : gridUsers) {
                            UserProject userProject = this.userProjectService.getOne(Wrappers.<UserProject>lambdaQuery()
                                    .eq(UserProject::getUserId, gridUser.getUserId())
                                    .eq(UserProject::getTenantId, user.getTenantId())
                                    .last(" limit 1")
                            );
                            GridRoleDTO gridRoleDTO = BeanUtil.copyProperties(gridUser, GridRoleDTO.class);
                            if (ObjectUtil.isNotNull(userProject)) {
                                gridRoleDTO.setRealname(userProject.getUserName());
                            } else {
                                gridRoleDTO.setUserId("");
                            }
                            gridRoleDTOS.add(gridRoleDTO);
                        }
                        gridInfoVO.setRoleList(gridRoleDTOS);
                    }
                    firstGridList.add(gridInfoVO);
                }
                if (2 == gridInfo.getGridLevel()) {
                    GridInfoVO gridInfoVO = BeanUtil.copyProperties(gridInfo, GridInfoVO.class);
                    // 查询用户信息
                    List<GridUser> gridUsers = iGridUserService.list(Wrappers.<GridUser>lambdaQuery().eq(GridUser::getGridId, gridInfoVO.getId()));
                    if (CollectionUtil.isNotEmpty(gridUsers)) {
                        List<GridRoleDTO> gridRoleDTOS = new ArrayList<>();
                        for (GridUser gridUser : gridUsers) {
                            UserProject userProject = this.userProjectService.getOne(Wrappers.<UserProject>lambdaQuery()
                                    .eq(UserProject::getUserId, gridUser.getUserId())
                                    .eq(UserProject::getTenantId, user.getTenantId())
                                    .last(" limit 1")
                            );
                            GridRoleDTO gridRoleDTO = BeanUtil.copyProperties(gridUser, GridRoleDTO.class);
                            if (ObjectUtil.isNotNull(userProject)) {
                                gridRoleDTO.setRealname(userProject.getUserName());
                            } else {
                                gridRoleDTO.setUserId("");
                            }
                            gridRoleDTOS.add(gridRoleDTO);
                        }
                        gridInfoVO.setRoleList(gridRoleDTOS);
                    }

                    // 获取三级网格
                    if (CollectionUtil.isNotEmpty(thirdGridMap)) {
                        GridInfo cgridInfo = thirdGridMap.get(gridInfo.getId());
                        if (ObjectUtil.isNotNull(cgridInfo)) {
                            GridInfoVO cgridInfoVO = BeanUtil.copyProperties(cgridInfo, GridInfoVO.class);
                            // 查询用户信息
                            List<GridUser> gridUsers2 = iGridUserService.list(Wrappers.<GridUser>lambdaQuery().eq(GridUser::getGridId, cgridInfoVO.getId()));
                            if (CollectionUtil.isNotEmpty(gridUsers2)) {
                                List<GridRoleDTO> gridRoleDTOS = new ArrayList<>();
                                for (GridUser gridUser : gridUsers2) {
                                    UserProject userProject = this.userProjectService.getOne(Wrappers.<UserProject>lambdaQuery()
                                            .eq(UserProject::getUserId, gridUser.getUserId())
                                            .eq(UserProject::getTenantId, user.getTenantId())
                                            .last(" limit 1")
                                    );
                                    GridRoleDTO gridRoleDTO = BeanUtil.copyProperties(gridUser, GridRoleDTO.class);
                                    if (ObjectUtil.isNotNull(userProject)) {
                                        gridRoleDTO.setRealname(userProject.getUserName());
                                    } else {
                                        gridRoleDTO.setUserId("");
                                    }
                                    gridRoleDTOS.add(gridRoleDTO);
                                }
                                cgridInfoVO.setRoleList(gridRoleDTOS);
                            }
                            gridInfoVO.setGridInfo(cgridInfoVO);
                        }
                    }
                    secondGridList.add(gridInfoVO);
                }
            }
            GridListVO gridListVO = new GridListVO();
            gridListVO.setFirstGridList(firstGridList);
            gridListVO.setSecondGridList(secondGridList);
            return RestBuilders.successBuilder().data(gridListVO).build();
        }
        return RestBuilders.errorBuilder().message("数据不存在，请先初始化一级网格配置").build();
    }

    /**
     * 获取网格下拉框数据
     *
     * @return site.morn.rest.RestMessage
     * @author Jereay
     * @date 2024/5/23 17:54
     */
    @Override
    public RestMessage querySelect() {
        List<GridInfo> gridInfoList = this.list(Wrappers.<GridInfo>lambdaQuery().eq(GridInfo::getGridLevel, 2));
        return RestBuilders.successBuilder().data(gridInfoList).build();
    }

    @Override
    public RestMessage queryInfoById(String id) {
        GridInfo gridInfo = this.getById(id);
        if (ObjectUtil.isNull(gridInfo)) {
            return RestBuilders.errorBuilder().message("数据不存在").build();
        }
        GridInfoVO gridInfoVO = BeanUtil.copyProperties(gridInfo, GridInfoVO.class);
        // 查询用户信息
        List<GridUser> gridUsers = iGridUserService.list(Wrappers.<GridUser>lambdaQuery().eq(GridUser::getGridId, gridInfoVO.getId()));
        if (CollectionUtil.isNotEmpty(gridUsers)) {
            List<GridRoleDTO> gridRoleDTOS = new ArrayList<>();
            for (GridUser gridUser : gridUsers) {
                UserProject userProject = this.userProjectService.getById(gridUser.getUserId());
                GridRoleDTO gridRoleDTO = BeanUtil.copyProperties(gridUser, GridRoleDTO.class);
                if (ObjectUtil.isNotNull(userProject)) {
                    gridRoleDTO.setRealname(userProject.getUserName());
                }
                gridRoleDTOS.add(gridRoleDTO);
            }
            gridInfoVO.setRoleList(gridRoleDTOS);
        }

        return RestBuilders.successBuilder().data(gridInfoVO).build();
    }

    /**
     * T配置网额用户
     *
     * @param gridUserDTO:
     * @return site.morn.rest.RestMessage
     * @author Jereay
     * @date 2024/5/16 09:54
     */
    @Override
    public RestMessage configUser(GridUserDTO gridUserDTO) {
        GridUser gridUser = new GridUser();
        gridUser.setId(gridUserDTO.getId());
        gridUser.setUserId(gridUserDTO.getUserId());
        boolean b = iGridUserService.updateById(gridUser);
        if (b) {
            return RestBuilders.successBuilder().message("配置成功").build();
        }
        return RestBuilders.errorBuilder().message("配置失败").build();
    }

    /**
     * 配置二维码
     *
     * @param gridQrDTO:
     * @return site.morn.rest.RestMessage
     * @author Jereay
     * @date 2024/5/16 09:57
     */
    @Override
    public RestMessage configQr(GridQrDTO gridQrDTO) {
        GridInfo gridInfo = new GridInfo();
        gridInfo.setId(gridQrDTO.getId());
        gridInfo.setQrCode(gridQrDTO.getQrCode());
        boolean b = this.updateById(gridInfo);
        if (b) {
            return RestBuilders.successBuilder().message("配置成功").build();
        }
        return RestBuilders.errorBuilder().message("配置失败").build();
    }

    /**
     * 查询配置的所有网格用户
     *
     * @return site.morn.rest.RestMessage
     * @author Jereay
     * @date 2024/5/23 17:40
     */
    @Override
    public RestMessage queryGridUserSelect(Integer gridId) {
        LinkappUser user = linkappUserContextProducer.getNotNullCurrent();
        List<GridUserSelectVO> gridUserSelectVOS = this.gridUserMapper.queryGridUserSelect(gridId, user.getTenantId());
        return RestBuilders.successBuilder().data(gridUserSelectVOS).build();
    }

    @Override
    public Map<Integer, GridInfo> mapByIds(Collection<Integer> ids) {
        if(CollUtil.isEmpty(ids)){
            return null;
        }
        List<GridInfo> list = this.list(Wrappers.<GridInfo>lambdaQuery().in(GridInfo::getId, ids));
        return CollectionUtils.convertMap(list, GridInfo::getId);
    }

    @Override
    public RestMessage delUser(Integer id) {
        GridUser gridUser = new GridUser();
        gridUser.setId(id);
        gridUser.setUserId(null);
        boolean b = iGridUserService.updateById(gridUser);
        if (b) {
            return RestBuilders.successBuilder().message("删除成功").build();
        }
        return RestBuilders.errorBuilder().message("删除失败").build();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestMessage del(Integer id) {
        GridInfo gridInfo = this.baseMapper.selectById(id);
        if (ObjectUtil.isNull(gridInfo)) {
            return RestBuilders.errorBuilder().message("数据不存在").build();
        }
        if (gridInfo.getGridLevel() == 1) {
            // 删除所有子级
            return RestBuilders.errorBuilder().message("一级网格不允许删除").build();
        }
        int i = this.gridInfoMapper.deleteById(id);
        if (i > 0) {
            // 删除网格用户
            iGridUserService.remove(Wrappers.<GridUser>lambdaQuery().eq(GridUser::getGridId, id));
            if (gridInfo.getGridLevel() == 2) {
                // 取消网格二维码关联
                if(StrUtil.isNotBlank(gridInfo.getQrCode())){
                    GridQrCode qrCode = this.gridQrCodeService.getOne(Wrappers.<GridQrCode>lambdaQuery()
                            .eq(GridQrCode::getCode, gridInfo.getQrCode())
                            .last(" limit 1")
                    );
                    if (ObjectUtil.isNotNull(qrCode)) {
                        this.gridQrCodeService.disassociate(String.valueOf(qrCode.getId()));
                    }
                }
                // 删除子网格
                List<GridInfo> gridInfos = this.baseMapper.selectList(Wrappers.<GridInfo>lambdaQuery().eq(GridInfo::getParentId, id));
                if (CollUtil.isNotEmpty(gridInfos)) {
                    for (GridInfo cgridInfo : gridInfos) {
                        this.gridInfoMapper.deleteById(cgridInfo.getId());
                        // 删除网格用户
                        iGridUserService.remove(Wrappers.<GridUser>lambdaQuery().eq(GridUser::getGridId, cgridInfo.getId()));
                    }
                }
            }

            return RestBuilders.successBuilder().message("删除成功").build();
        }
        return RestBuilders.errorBuilder().message("删除失败").build();
    }
}